#include <SPI.h>

#define KEY1 PA5
#define KEY2 PA6
#define KEY3 PB3

#define LED1 PB0
#define LED2 PB2
#define LED3 PB1
#define LED4 PA7

#define WS2812_N 1

unsigned char WS2812_T[WS2812_N][3] = {0};

void setup(void) {
    Serial.begin(9600);
    Serial.println("setup");

    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(LED3, OUTPUT);

    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
    digitalWrite(LED3, HIGH);

    pinMode(KEY1, INPUT_PULLUP);
    pinMode(KEY2, INPUT_PULLUP);
    pinMode(KEY3, INPUT_PULLUP);

    //初始化SPI
    SPI.begin();
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE1);
    // 这里需要让SPI处于8MHz
    // 所以芯片要设置16M，SPI配置为2分频：
    SPI.setClockDivider(SPI_CLOCK_DIV2);
    delay(10);

    WS2812_refresh();
}

int last_state1 = LOW;
int last_state2 = LOW;
int last_state3 = LOW;

void check_key_status(void) {
    int state1 = digitalRead(KEY1);
    int state2 = digitalRead(KEY2);
    int state3 = digitalRead(KEY3);

    if (last_state1 != state1) {
        last_state1 = state1;
        digitalWrite(LED1, !state1);

        if (state1) {
            WS2812_T[0][0] = 10; // R
            WS2812_T[0][1] = 0;  // G
            WS2812_T[0][2] = 0;  // B
        } else {
            clean_ws2812();
        }

        WS2812_refresh();
    }

    if (last_state2 != state2) {
        last_state2 = state2;
        digitalWrite(LED2, !state2);

        if (state2) {
            WS2812_T[0][0] = 0;
            WS2812_T[0][1] = 10;
            WS2812_T[0][2] = 0;
        } else {
            clean_ws2812();
        }

        WS2812_refresh();
    }

    if (last_state3 != state3) {
        last_state3 = state3;
        digitalWrite(LED3, !state3);

        if (state3) {
            WS2812_T[0][0] = 10;
            WS2812_T[0][1] = 10;
            WS2812_T[0][2] = 10;
        } else {
            clean_ws2812();
        }

        WS2812_refresh();
    }
}

void clean_ws2812() {
    WS2812_T[0][0] = 0;
    WS2812_T[0][1] = 0;
    WS2812_T[0][2] = 0;
}

void loop() { check_key_status(); }

void WS2812_send(unsigned char r, unsigned char g, unsigned char b) {
    unsigned char bits = 24;
    unsigned long value = 0x00000000;
    value = (((unsigned long)g << 16) | ((unsigned long)r << 8) |
             ((unsigned long)b));
    while (bits > 0) {
        if ((value & 0x800000) != LOW) {
            SPI.transfer(0xF8); // 1
            asm("nop");
            asm("nop");
        } else {
            SPI.transfer(0xC0); // 0
        }
        value <<= 1;
        bits--;
    }
}

void WS2812_refresh() {
    unsigned int n = 0;
    for (n = 0; n < WS2812_N; n++) {
        WS2812_send(WS2812_T[n][0], WS2812_T[n][1], WS2812_T[n][2]);
    }
    delayMicroseconds(60);
}
